package com.story.api.moduler.song.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.github.pagehelper.PageHelper;
import com.story.api.common.persistence.dao.*;
import com.story.api.common.persistence.model.*;
import com.story.api.common.result.PageResult;
import com.story.api.common.util.PageBeanUtil;
import com.story.api.config.properties.UpyunProperties;
import com.story.api.moduler.song.dao.RecommendDao;
import com.story.api.moduler.song.dao.VedioCategoryDao;
import com.story.api.moduler.song.dao.VedioDetailDao;
import com.story.api.moduler.song.service.SongV2Service;
import com.story.api.moduler.song.transfer.BannerVo;
import com.story.api.moduler.song.transfer.vo.AlbumVo;
import com.story.api.moduler.song.transfer.vo.BannerAndAlbumVo;
import com.story.api.moduler.song.transfer.vo.MediaResourceVo;
import com.story.api.moduler.song.transfer.vo.recommend.RecommendVo;
import com.story.api.moduler.upyun.service.UpyunService;
import com.story.core.util.UriUtil;
import org.apache.commons.lang.math.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * v2 版
 * @author yangbo
 * @date 2019-07-09 8:43
 */
@Service
public class SongV2ServiceImpl implements SongV2Service {

    private static final Logger log = LoggerFactory.getLogger(SongV2Service.class);

    private static final Long EXPIRE_TIME = 36000L;

    @Autowired
    private RecommendDao recommendDao;

    @Autowired
    private UpyunProperties upyunProperties;

    @Autowired
    private UpyunService upyunService;

    @Autowired
    private VedioDetailDao videiDetailDao;

    @Autowired
    private AgeTypeMapper ageTypeMapper;

    @Autowired
    private BannerMapper bannerMapper;

    @Autowired
    private BannerCateMapper bannerCateMapper;

    @Autowired
    private VedioCategoryDao vedioCategoryDao;

    @Autowired
    private VedioCategoryMapper vedioCategoryMapper;

    @Autowired
    private VedioDetailDao vedioDetailDao;

    @Autowired
    private CateVedioMapper cateVedioMapper;

    /**
     * 得到推荐位列表
     * @return
     */
    @Override
    public List<RecommendVo> getRecommendList(Integer templateId) {
        List<RecommendVo> recommendVoList = recommendDao.recommendList(templateId);
        recommendVoList = recommendVoList.stream().map(this::getFullRecommendPicPath)
                .collect(Collectors.toList());
        return recommendVoList;
    }

    /**
     * 按推荐指数分页排序
     * @param ageRange
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public PageResult getMediaPageList(Integer ageRange, Integer pageNo, Integer pageSize) {
        PageHelper.startPage(pageNo,pageSize);
        List<MediaResourceVo> mediaResourceVoList = videiDetailDao.getRankedVideoList(ageRange);
        PageResult<MediaResourceVo> pageResult = PageBeanUtil.toPageResult(mediaResourceVoList);
        List<MediaResourceVo> mediaResourceVos = new ArrayList<>(mediaResourceVoList.size());
        for (MediaResourceVo mediaResourceVo : mediaResourceVoList) {
            MediaResourceVo mediaResource = new MediaResourceVo();
            BeanUtils.copyProperties(mediaResourceVo,mediaResource);
            //图片地址
            mediaResource.setPicPath(addTokenUrl(mediaResourceVo.getPicPath()));
            //产品名称
            mediaResource.setProductName("口袋儿歌");
            //下载地址
            mediaResource.setDownloadPath(addTokenUrl(mediaResourceVo.getDownloadPath()));
            //播放次数
            mediaResourceVo.setPlayCount(mediaResourceVo.getPlayCount());
            mediaResourceVos.add(mediaResource);
        }
        pageResult.setDataList(mediaResourceVos);
        return pageResult;
    }

    /**
     * 得到年龄段数据
     * @return
     */
    @Override
    public List<AgeType> getAges() {
        List<AgeType> ageTypeList = ageTypeMapper.selectList(new EntityWrapper<>());
        ageTypeList = ageTypeList.stream()
                .sorted( Comparator.comparing(AgeType::getType))
                .collect( Collectors.toList());
        return ageTypeList;
    }

    /**
     * 栏目列表
     * @return
     */
    @Override
    public List<BannerVo> bannerList(Integer type) {
        List<Banner> bannerList = bannerMapper.selectList(new EntityWrapper<Banner>().eq("type",type));
        bannerList = bannerList.stream()
                .sorted(Comparator.comparing(Banner::getRank).reversed())
                .collect( Collectors.toList());
        List<BannerVo> bannerVoList = new ArrayList<>(bannerList.size());
        for (Banner banner : bannerList) {
            BannerVo bannerVo = new BannerVo();
            BeanUtils.copyProperties(banner,bannerVo);
            bannerVo.setIconPath(addTokenUrl(bannerVo.getIconPath()));
            bannerVoList.add(bannerVo);
        }
        return bannerVoList;
    }

    /**
     * 获取专辑前6个
     * @param type
     * @return
     */
    @Override
    public List<AlbumVo> recommendAlbum(Integer type) {
        List<AlbumVo> albumVoList = vedioCategoryDao.getAlbumListByResType(type);
        List<AlbumVo> albumVos = new ArrayList<>(albumVoList.size());
        for (AlbumVo albumVo : albumVoList) {
            albumVo.setIconPath(addTokenUrl(albumVo.getIconPath()));
            //播放次数
            int playCount = 0;
            List<Integer> vedioIdList = cateVedioMapper
                    .selectList(new EntityWrapper<CateVedio>().eq("cateId",albumVo.getId()))
                    .stream()
                    .map(CateVedio::getVedioId)
                    .collect( Collectors.toList());
            if(!vedioIdList.isEmpty()) {
                playCount = vedioDetailDao.playCountSum(vedioIdList);
            }
            albumVo.setPlayCount(playCount);
            Integer count = cateVedioMapper.selectCount(new EntityWrapper<CateVedio>().eq("cateId",albumVo.getId()));
            albumVo.setCollects(count);
            albumVos.add(albumVo);
        }
        return albumVoList;
    }

    /**
     * 栏目与专辑列表
     * @param type
     * @return
     */
    @Override
    public List<BannerAndAlbumVo> bannerAndAlbumList(Integer type) {
        //栏目列表
        List<BannerVo> bannerVoList = bannerList(type);
        List<BannerAndAlbumVo> bannerAndAlbumVoList = new ArrayList<>(bannerVoList.size());
        for (BannerVo bannerVo : bannerVoList) {
            BannerAndAlbumVo bannerAndAlbumVo = new BannerAndAlbumVo();
            BeanUtils.copyProperties(bannerVo,bannerAndAlbumVo);
            //专辑部分
            List<AlbumVo> albumVoList = vedioCategoryDao.getAlbumListByResTypeAndBannerId(type,bannerAndAlbumVo.getId());
            albumVoList = albumVoList.stream().map(this::getFullPathAlbum)
                    .collect( Collectors.toList());
            bannerAndAlbumVo.setAlbumList(albumVoList);
            bannerAndAlbumVoList.add(bannerAndAlbumVo);
        }
        return bannerAndAlbumVoList;
    }

    /**
     * 栏目下的专辑列表
     * @param bannerId
     * @return
     */
    @Override
    public PageResult albumList(Integer bannerId,Integer pageNo,Integer pageSize) {
        PageHelper.startPage(pageNo,pageSize);
        List<VedioCategory> vedioCategories = vedioCategoryDao.getVedioCategoryByBannerId(bannerId);
        PageResult pageResult = PageBeanUtil.toPageResult(vedioCategories);
        List<AlbumVo> albumVoList = new ArrayList<>(vedioCategories.size());
        for (VedioCategory category : vedioCategories) {
            AlbumVo albumVo = new AlbumVo();
            albumVo.setId(category.getId());
            albumVo.setName(category.getName());
            albumVo.setIntro(category.getIntro());
            albumVo.setIconPath(addTokenUrl(category.getIconPath()));
            albumVo.setCollects(cateVedioMapper
                    .selectCount(new EntityWrapper<CateVedio>().eq("cateId",albumVo.getId())));
            //播放次数，分享量
            int playCount = 0;
            int shareCount = 0;
            List<Integer> vedioIdList = cateVedioMapper
                    .selectList(new EntityWrapper<CateVedio>().eq("cateId",albumVo.getId()))
                    .stream()
                    .map(CateVedio::getVedioId)
                    .collect( Collectors.toList());
            if(!vedioIdList.isEmpty()) {
                playCount = vedioDetailDao.playCountSum(vedioIdList);
                shareCount = vedioDetailDao.shareCountSum(vedioIdList);
            }
            albumVo.setPlayCount(playCount);
            albumVo.setShareCount(shareCount);
            albumVoList.add(albumVo);
        }
        pageResult.setDataList(albumVoList);
        return pageResult;
    }

    /**
     * 专辑下视频列表
     * @param albumId
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public PageResult mediaList(Integer albumId, Integer pageNo, Integer pageSize) {
        PageHelper.startPage(pageNo,pageSize);
        List<VedioDetail> vedioDetailList = vedioDetailDao.getVedioDetaiPageByCateId(albumId);
        PageResult pageResult = PageBeanUtil.toPageResult(vedioDetailList);
        VedioCategory category = vedioCategoryMapper.selectById(albumId);
        List<MediaResourceVo> mediaResourceVoList = new ArrayList<>(vedioDetailList.size());
        for(VedioDetail vedioDetail : vedioDetailList) {
            MediaResourceVo mediaResourceVo = new MediaResourceVo();
            BeanUtils.copyProperties(vedioDetail,mediaResourceVo);
            mediaResourceVo.setPicPath(addTokenUrl(vedioDetail.getLogoPath()));
            mediaResourceVo.setPlayPath(upyunProperties.getDomain() + vedioDetail.getFilePath());
            mediaResourceVo.setType(category.getType());
            mediaResourceVo.setPlayCount(mediaResourceVo.getPlayCount());
            mediaResourceVoList.add(mediaResourceVo);
        }
        pageResult.setDataList(mediaResourceVoList);
        return pageResult;
    }

    /**
     * 专辑详情
     * @param albumId
     * @return
     */
    @Override
    public AlbumVo albumDetail(Integer albumId) {
        VedioCategory vedioCategory = vedioCategoryMapper.selectById(albumId);
        if(vedioCategory == null) {
            return new AlbumVo();
        }
        AlbumVo albumVo = new AlbumVo();
        BeanUtils.copyProperties(vedioCategory,albumVo);
        albumVo.setIconPath(addTokenUrl(vedioCategory.getIconPath()));
        albumVo.setCollects(cateVedioMapper
                .selectCount(new EntityWrapper<CateVedio>().eq("cateId",albumVo.getId())));
        //播放次数，分享量
        int playCount = 0;
        int shareCount = 0;
        List<Integer> vedioIdList = cateVedioMapper
                .selectList(new EntityWrapper<CateVedio>().eq("cateId",albumVo.getId()))
                .stream()
                .map(CateVedio::getVedioId)
                .collect( Collectors.toList());
        if(!vedioIdList.isEmpty()) {
            playCount = vedioDetailDao.playCountSum(vedioIdList);
            shareCount = vedioDetailDao.shareCountSum(vedioIdList);
        }
        albumVo.setPlayCount(playCount);
        albumVo.setShareCount(shareCount);
        return albumVo;
    }

    /**
     * 相似专辑
     * @param albumId
     * @return
     */
    @Override
    public List<AlbumVo> similarList(Integer albumId) {
        VedioCategory vedioCategory = vedioCategoryMapper.selectById(albumId);
        Integer resType = vedioCategory.getResType();
        List<BannerCate> bannerCateList = bannerCateMapper
                .selectList(new EntityWrapper<BannerCate>().eq("cateId",albumId));
        List<Integer> bannerIdList = bannerCateList.stream()
                .map(BannerCate::getBannerId).collect(Collectors.toList());
        List<Banner> bannerList = bannerMapper.selectBatchIds(bannerIdList);
        bannerList = bannerList.stream()
                .filter(banner -> resType.equals(banner.getType())).collect(Collectors.toList());
        Integer bannerId;
        if(bannerList.size() != 0) {
            Banner banner = bannerList.get(0);
            bannerId = banner.getId();
        } else {
            return new ArrayList<>();
        }
        List<VedioCategory> vedioCategories = vedioCategoryDao.getVedioCategoryByBannerId(bannerId);
        vedioCategories = vedioCategories.stream()
                .filter(cate -> !albumId.equals(cate.getId())).limit(6).collect(Collectors.toList());
        List<AlbumVo> albumVoList = new ArrayList<>(vedioCategories.size());
        for (VedioCategory category : vedioCategories) {
            AlbumVo albumVo = new AlbumVo();
            albumVo.setName(category.getName());
            albumVo.setId(category.getId());
            albumVo.setIntro(category.getIntro());
            albumVo.setIconPath(addTokenUrl(category.getIconPath()));
            albumVo.setCollects(cateVedioMapper
                    .selectCount(new EntityWrapper<CateVedio>().eq("cateId",albumVo.getId())));
            //播放次数，分享量
            int playCount = 0;
            int shareCount = 0;
            List<Integer> vedioIdList = cateVedioMapper
                    .selectList(new EntityWrapper<CateVedio>().eq("cateId",albumVo.getId()))
                    .stream()
                    .map(CateVedio::getVedioId)
                    .collect( Collectors.toList());
            if(!vedioIdList.isEmpty()) {
                playCount = vedioDetailDao.playCountSum(vedioIdList);
                shareCount = vedioDetailDao.shareCountSum(vedioIdList);
            }
            albumVo.setPlayCount(playCount);
            albumVo.setShareCount(shareCount);
            albumVoList.add(albumVo);
        }
        return albumVoList;
    }


    /**
     * 得到完整的推荐位图片路径
     * @param recommendVo
     * @return
     */
    private RecommendVo getFullRecommendPicPath(RecommendVo recommendVo) {
        recommendVo.setPicPath(addTokenUrl(recommendVo.getPicPath()));
        return recommendVo;
    }

    /**
     * 得到专辑的完整图片路径
     * @param albumVo
     * @return
     */
    private AlbumVo getFullPathAlbum(AlbumVo albumVo) {
        albumVo.setIconPath(addTokenUrl(albumVo.getIconPath()));
        return albumVo;
    }

    /**
     * 对url添加token,防止盗链
     * @param url
     * @return
     */
    private String addTokenUrl(String url) {
        return upyunProperties.getDomain() + url + "?_upt=" + upyunService.getTokenSign(UriUtil.getUri(url),EXPIRE_TIME);
    }
}
